package com.zshan.clinic.common.util.string;

import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.exception.BusinessFailException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串处理
 */
@Slf4j
public class StringUtil extends StringUtils {

    private static final String[] CHINESE_DIGITS =
            {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
    private static final String[] UNITS = {"", "十", "百", "千"};

    public static String normalizeRecoms(String recoms) {
        if (isBlank(recoms)) {
            return null;
        }
        // 1. 把英文逗号和中文逗号都换成空格
        String s = recoms.replace(',', ' ')
                .replace('，', ' ');
        // 2. 把可能出现的连续空格压成一个
        s = s.trim().replaceAll("\\s+", " ");
        return s;
    }


    /**
     *
     * @param subStr
     * @return
     */
    public static String subString50(String subStr){
        if(StringUtil.isBlank(subStr)){
            return null;
        }
        if(subStr.length() > CommonConstant.DEFAULT_50){
            subStr = substring(subStr,CommonConstant.DEFAULT_0,CommonConstant.DEFAULT_50);
        }
        return subStr;
    }

    /**
     * 去除字符串中所有空白字符，包括空格、制表符、换行符等
     * @param input 原始字符串
     * @return 处理后的字符串；若 input 为 null，则返回 null
     */
    public static String removeAllWhitespace(String input) {
        return input == null ? null : input.replaceAll("\\s+", "");
    }

    /**
     * 将 0~9999 的整数转为中文小写汉字
     */
    public static String toChinese(int number) {
        if (number < 0 || number > 9999) {
            throw new IllegalArgumentException("仅支持 0~9999 的整数");
        }

        if (number == 0) {
            return CHINESE_DIGITS[0];
        }

        StringBuilder sb = new StringBuilder();
        String numStr = String.valueOf(number);
        int len = numStr.length();
        boolean zeroFlag = false;

        for (int i = 0; i < len; i++) {
            int digit = numStr.charAt(i) - '0';
            int pos = len - i - 1;

            if (digit == 0) {
                zeroFlag = true;
            } else {
                if (zeroFlag) {
                    sb.append(CHINESE_DIGITS[0]);
                    zeroFlag = false;
                }
                sb.append(CHINESE_DIGITS[digit]).append(UNITS[pos]);
            }
        }

        String result = sb.toString();

        // 特殊处理：10~19 应为“十X”而不是“一十X”
        if (number >= 10 && number < 20) {
            result = result.replaceFirst("一十", "十");
        }

        return result;
    }


    public static boolean isBlank(Integer id) {
        if(id == null || id == 0){
            return true;
        }
        return false;
    }

    public static boolean isBlank(Long id) {
        if(id == null || id == 0L){
            return true;
        }
        return false;
    }

    /**
     * 字符串转int
     * @param str
     * @return
     */
    public static Integer str2Int(String str){
        try{
            if(str == null){
                return null;
            }
            return Integer.parseInt(str);
        }catch (Exception e){
            return null;
        }
    }

    /**
     * object转str
     * @param object
     * @return
     */
    public static String obj2Str(Object object){
        try{
            if(object == null){
                return null;
            }
            if (object instanceof String){
                return object.toString();
            }
        }catch (Exception e){
            return null;
        }
        return null;
    }


    /**
     * object转int
     * @param object
     * @return
     */
    public static Integer obj2Int(Object object){
        try{
            if(object == null){
                return null;
            }
            if(object instanceof Integer){
                return (Integer) object;
            }
            if (object instanceof String){
                return Integer.parseInt(object.toString());
            }
        }catch (Exception e){
            return null;
        }
        return null;
    }




    /**
     *
     * @param subStr
     * @return
     */
    public static String subString(String subStr,int length){
        if(StringUtil.isBlank(subStr)){
            return null;
        }
        if(subStr.length() > length){
            subStr = substring(subStr,CommonConstant.DEFAULT_0,length);
        }
        return subStr;
    }


    public static String unicodeToString(String str) {
        if (isBlank(str)) {
            return null;
        }
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = pattern.matcher(str);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            str = str.replace(matcher.group(1), ch + "");
        }
        return str;
    }


    public static void checkPassword(String password) {
        if (StringUtil.isBlank(password)) {
            throw new BusinessFailException("密码不能为空");
        }
        if (password.length() < 8 || password.length() > 16) {
            throw new BusinessFailException("请输入8~16位的字母、数字");
        }
        boolean flag = false;
        try {
            //验证手机号
            Pattern p = Pattern.compile("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$");
            Matcher m = p.matcher(password);
            flag = m.matches();
        } catch (Exception e) {
        }
        if (!flag) {
            throw new BusinessFailException("请输入8~16位的字母、数字");
        }
    }


    public static void checkUserPhone(String phone) {
        if (StringUtil.isBlank(phone)) {
            throw new BusinessFailException("手机号不能为空");
        }
        if (phone.length() > 11) {
            throw new BusinessFailException("手机号长度不能超过11");
        }
        boolean flag = false;
        try {
            //验证手机号
            Pattern p = Pattern.compile("^1[3|4|5|6|7|8|9][0-9]\\d{8,8}$");
            Matcher m = p.matcher(phone);
            flag = m.matches();
        } catch (Exception e) {
            log.error("验证用户手机号失败，手机号:{}", phone);
        }
        if (!flag) {
            throw new BusinessFailException("用户手机号格式错误");
        }
    }

    private static Pattern linePattern = Pattern.compile("_(\\w)");


    public static String join(String split, String... values) {
        StringBuilder builder = new StringBuilder();
        String[] arr$ = values;
        int len$ = values.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String s = arr$[i$];
            builder.append(s).append(split);
        }

        return removeEndCharacter(builder.toString().trim(), split);
    }

    public static String removeEndCharacter(String string, String endCharacter) {
        if (StringUtils.isNotBlank(string) && string.endsWith(endCharacter)) {
            string = string.substring(0, string.length() - endCharacter.length());
        }

        return string;
    }


    /**
     * 查询字符串中的特定字符数
     *
     * @param target
     * @param ch
     * @return
     */
    public static int countChar(String target, char ch) {
        int count = 0;
        if (StringUtils.isNotBlank(target)) {
            for (int i = 0; i < target.length(); i++) {
                if (target.charAt(i) == ch) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * 下划线转驼峰
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 驼峰转下划线
     */
    public static String humpToLine(String str) {
        return str.replaceAll("[A-Z]", "_$0").toLowerCase();
    }

    /**
     * 驼峰转下划线(多字段排序)
     */
    public static String humpToLineForMorAttr(String column, String order) {
        StringBuilder result = null;
        if (StringUtils.isEmpty(column)) {
            return null;
        }
        String str = column.replaceAll("[A-Z]", "_$0").toLowerCase();
        if (str.contains(",")) {
            result = new StringBuilder();
            String[] split = str.split(",");
            for (String col : split) {
                result.append(col).append(" ").append(order).append(",");
            }
            return result.toString().substring(0, result.length() - 1);
        } else {
            return str + " " + order;
        }
    }

    public static String valueOf(Object obj) {
        return (obj == null) ? null : obj.toString();
    }

    public static String append(String... strs) {
        StringBuilder builder = new StringBuilder();
        String[] arr$ = strs;
        int len$ = strs.length;
        for (int i$ = 0; i$ < len$; ++i$) {
            String s = arr$[i$];
            if (!StringUtil.isBlank(s)) {
                builder.append(s);
            }
        }

        return builder.toString().trim();
    }


    public static boolean isNotBlank(String... strs) {
        if (null == strs) {
            return false;
        } else {
            String[] arr$ = strs;
            int len$ = strs.length;
            for (int i$ = 0; i$ < len$; ++i$) {
                String str = arr$[i$];
                if (StringUtils.isNotBlank(str)) {
                    return true;
                }
            }
            return false;
        }
    }


    public static boolean hasEmpty(String... strs) {
        String[] arr$ = strs;
        int len$ = strs.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String str = arr$[i$];
            if (StringUtils.isEmpty(str)) {
                return true;
            }
        }

        return false;
    }

    public static boolean allEmpty(String... strs) {
        String[] arr$ = strs;
        int len$ = strs.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String str = arr$[i$];
            if (StringUtils.isNotEmpty(str)) {
                return false;
            }
        }

        return true;
    }


    public static boolean equals(String target, String... strs) {
        String[] arr$ = strs;
        int len$ = strs.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String str = arr$[i$];
            if (StringUtils.equals(target, str)) {
                return true;
            }
        }

        return false;
    }


    public static boolean hasBlank(String... strs) {
        String[] arr$ = strs;
        int len$ = strs.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String str = arr$[i$];
            if (StringUtils.isBlank(str)) {
                return true;
            }
        }

        return false;
    }

    public static String[] getStrArrayByStrList(List<String> list) {
        String[] result = null;

        for (int i = 0; i < list.size(); ++i) {
            ((Object[]) result)[i] = (String) list.get(i);
        }

        return (String[]) result;
    }

    public static boolean hasEmptyObj(Object... objects) {
        Object[] arr$ = objects;
        int len$ = objects.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            Object object = arr$[i$];
            if (StringUtils.isEmpty((String) object)) {
                return true;
            }
        }

        return false;
    }

    public static boolean isNotEmptyObj(Object object) {
        return !StringUtils.isEmpty((String) object);
    }

    public static boolean isEmptyObj(Object object) {
        String str = (String) object;
        return str == null || str.length() == 0;
    }

    public static boolean keysHasEmpty(Map map, String... keys) {
        String[] arr$ = keys;
        int len$ = keys.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String key = arr$[i$];
            if (StringUtils.isEmpty((String) map.get(key))) {
                return true;
            }
        }

        return false;
    }

    /**
     * 字符串是否数字
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 判断是否是数字
     *
     * @param num
     * @return
     */
    public static boolean isNumber(String num) {
        if (NumberUtils.isNumber(num)
                && !num.contains("d") && !num.contains("D")
                && !num.contains("l") && !num.contains("L")
                && !num.contains("f") && !num.contains("F")) {
            return true;
        }
        return false;
    }


    /**
     * 验证邮箱
     *
     * @param email
     * @return
     */
    public static boolean checkEmail(String email) {
        boolean flag = false;
        try {
            String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
            Pattern regex = Pattern.compile(check);
            Matcher matcher = regex.matcher(email);
            flag = matcher.matches();
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 空串转换
     *
     * @param str
     * @return
     */
    public static String nullToStr(String str) {
        return StringUtils.isBlank(str) ? "" : str;
    }

    /**
     * 检验qq
     *
     * @return
     */
    public static boolean checkQQ(String qq) {
        return qq.matches("[1-9][0-9]{4,11}");
    }

    /**
     * 判断的是否是正整数
     *
     * @param num
     * @return
     */
    public static boolean isPositiveInteger(String num) {
        if (num == null) {
            return false;
        }
        String regex = "^[1-9]\\d*$";
        return num.matches(regex);
    }


    public static Pattern pattern = Pattern.compile("[\\s\\p{Zs}]+");

    /**
     * 手机号脱敏
     *
     * @return
     */
    public static String phoneDesensitization(String phone) {
        return phone.replaceAll("(\\w{3})\\w*(\\w{4})", "$1****$2");
    }



    /**
     * 名称脱敏
     *
     * @param name
     * @return
     */
    public static String nameDesensitization(String name) {
        if (StringUtil.isBlank(name)) {
            return null;
        }
        if (name.length() < 5) {
            return name;
        }
        return name.substring(0, 2) + "**" + name.substring(name.length() - 2);
    }

    /**
     * 计算字数
     *
     * @param context
     * @return
     */
    public static int contentLength(String context) {
        if (StringUtil.isBlank(context)) {
            return 0;
        }
        int words_count = 0;
        //中文单词
        String cn_words = context.replaceAll("[^\\u4e00-\\u9fa5，。《》？；’‘：“”【】、）（……￥！·１２３４５６７８９０ＱＷＥＲＴＹＵＩＯＰＡＳＤＦＧＨＪＫＬＺＸＣＶＢＮＭｑｗｅｒｔｙｕｉｏｐａｓｄｆｇｈｊｋｌｚｘｃｖｂｎｍ｀－＝［］＼；＇，．／～！＠＃＄％＾＆＊（）＿＋｛｝｜：＂＜＞？～！＃￥……×——“”《》【】；‘，。、·]", "");
        int cn_words_count = cn_words.length();
        //非中文单词
        String non_cn_words = context.replaceAll("[^(a-zA-Z0-9`\\-=\';.,/~!@#$%^&*()_+|}{\":><?\\[\\])]", " ");
        int non_cn_words_count = 0;
        String[] ss = non_cn_words.split(" ");
        for (String s : ss) {
            if (s.trim().length() != 0) {
                non_cn_words_count++;
            }
        }
        //中文和非中文单词合计
        words_count = cn_words_count + non_cn_words_count;
        return words_count;
    }

    /**
     * 多个/r/n替换成一个
     * （不支持中文全角）
     *
     * @param str
     * @return
     */
    public static String replaceLineBlanks(String str) {
        String result = "";
        if (str != null) {
            str = str.replaceAll("\n+", "\n");
            Pattern p = Pattern.compile("(\r?\n(\\s*\r?\n)+)");
            Matcher m = p.matcher(str);
            result = m.replaceAll("\r\n");
        }
        return result;
    }


    /**
     * 多个空行替换为一个
     * （支持中文全角， 中文空格全部替换，英文空格保留一个）
     * 章节内容、帖子内容
     *
     * @param str
     * @return
     */
    public static String replaceAllLineBlanks(String str) {
        if (StringUtil.isBlank(str)) {
            return "";
        }
        String s = replaceLineBlanks(str);
        String[] as = s.split("\n");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < as.length; i++) {
            String pra = as[i];
            String repStr = replaceAll(pra);
            if (StringUtil.isBlank(repStr)) {
                continue;
            }
            sb.append("　　" + manageAllBlank(pra.trim()));
            if (i != as.length - 1) {
                sb.append("\n");
            }
        }
        String result = sb.toString();
        if (result.endsWith("\n")) {
            result = result.substring(0, result.lastIndexOf("\n"));
        }
        return result;
    }


    /**
     * 多个空行空格变成一个（不区分中英文）
     * 昵称，章节名
     */
    public static String replaceAllLineBlanksToOne(String str) {
        if (StringUtil.isBlank(str)) {
            return "";
        }
        String s = replaceLineBlanks(str);
        String[] as = s.split("\n");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < as.length; i++) {
            String pra = as[i];
            String repStr = replaceAll(pra);
            if (StringUtil.isBlank(repStr)) {
                continue;
            }
            sb.append(manageOneBlank(pra.trim()));
            if (i != as.length - 1) {
                sb.append("\n");
            }
        }
        String result = sb.toString();
        if (result.endsWith("\n")) {
            result = result.substring(0, result.lastIndexOf("\n"));
        }
        return result;
    }

    private static String manageAllBlank(String value) {
        value = replaceBegin(replaceEnd(value));
        try {
            value = allBlanks(value);
        } catch (Exception e) {
            log.error("处理中间空格异常：", e);
        }
        return value;
    }

    private static String manageOneBlank(String value) {
        value = replaceBegin(replaceEnd(value));
        try {
            value = allBlanksToOne(value);
        } catch (Exception e) {
            log.error("处理中间空格异常：", e);
        }
        return value;
    }


    private static String replaceAll(String value) {
        return value.replaceAll("[ 　\\t|]*", "");
    }

    private static String replaceBegin(String value) {
        return value.replaceAll("^[ 　 \\t]*", "");
    }

    private static String replaceEnd(String value) {
        return value.replaceAll("[ 　 \\t]*$", "");
    }

    private static String allBlanksToOne(String value) {
        String blankReg = "[　| | | ]+";
        String oneBlank = value.trim().replaceAll(blankReg, " ");
        return oneBlank;
    }

    private static String allBlanks(String value) {
        String blankReg = "[　| | | ]+";
        StringBuffer sb = new StringBuffer();
        String oneBlank = value.trim().replaceAll(blankReg, " ");
        String[] partArray = oneBlank.split(" ");
        for (int j = 0; j < getDichotomizeArray(partArray); j++) {
            String before = partArray[j * 2];
            if (j > 0) {
                addBlank(sb, partArray[j * 2 - 1], before);
            }
            sb.append(before);
            if (2 * j + 1 > partArray.length - 1) {
                continue;
            }
            String after = partArray[j * 2 + 1];
            if (!StringUtil.isBlank(after)) {
                addBlank(sb, partArray[j * 2], after);
                sb.append(after);
            }
        }
        return sb.toString();
    }

    // 非汉字中间添加空格
    private static void addBlank(StringBuffer stringBuffer, String beforeWord, String afterWord) {
        if (StringUtil.isBlank(beforeWord) || StringUtil.isBlank(afterWord)) {
            return;
        }
        String chineseWordReg = "^[\\u4E00-\\u9FA5]+$";
        //该行从字符串 beforeWord 中获取最后一个字符，然后将其存储在变量 part1 中
        String part1 = beforeWord.substring(beforeWord.length() - 1);
        String part2 = afterWord.substring(0, 1);
        if (!(part1.matches(chineseWordReg) && part2.matches(chineseWordReg))) {
            stringBuffer.append(" ");
        }
    }

    private static int getDichotomizeArray(String[] partArray) {
        if (partArray.length % 2 == 0) {
            return partArray.length / 2;
        }
        return partArray.length / 2 + 1;
    }
}













